package com.smartcampusbackend.service.impl;

import com.smartcampusbackend.model.LeaveApplication;
import com.smartcampusbackend.model.Course;
import com.smartcampusbackend.model.StudentCourse;
import com.smartcampusbackend.model.User;
import com.smartcampusbackend.mapper.LeaveApplicationMapper;
import com.smartcampusbackend.mapper.CourseMapper;
import com.smartcampusbackend.mapper.StudentCourseMapper;
import com.smartcampusbackend.mapper.UserMapper;
import com.smartcampusbackend.service.LeaveApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

@Service
public class LeaveApplicationServiceImpl implements LeaveApplicationService {
    private static final Logger logger = LoggerFactory.getLogger(LeaveApplicationServiceImpl.class);
    
    @Autowired
    private LeaveApplicationMapper leaveApplicationMapper;
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private StudentCourseMapper studentCourseMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean submitLeaveApplication(LeaveApplication application) {
        // 设置初始状态为待审批
        application.setStatus("PENDING");
        logger.info("提交请假申请: {}", application);
        return leaveApplicationMapper.insert(application) > 0;
    }

    @Override
    public boolean approveLeaveApplication(Long applicationId, boolean approved, String rejectReason) {
        logger.info("开始处理请假审批: applicationId={}, approved={}, rejectReason={}", applicationId, approved, rejectReason);
        
        LeaveApplication application = leaveApplicationMapper.selectById(applicationId);
        if (application == null) {
            logger.error("未找到请假申请ID: {}", applicationId);
            return false;
        }
        
        logger.info("当前请假申请状态: {}", application.getStatus());
        
        try {
            application.setStatus(approved ? "APPROVED" : "REJECTED");
            if (!approved && rejectReason != null && !rejectReason.isEmpty()) {
                application.setRejectReason(rejectReason);
                logger.info("拒绝请假申请ID: {}, 原因: {}", applicationId, rejectReason);
            } else {
                logger.info("批准请假申请ID: {}", applicationId);
            }
            
            int result = leaveApplicationMapper.updateById(application);
            logger.info("更新请假申请结果: {}", result > 0 ? "成功" : "失败");
            return result > 0;
        } catch (Exception e) {
            logger.error("处理请假审批时发生错误: ", e);
            return false;
        }
    }

    @Override
    public List<LeaveApplication> listStudentLeaveApplications(Long studentId) {
        logger.info("获取学生请假申请记录, 学生ID: {}", studentId);
        return leaveApplicationMapper.selectList(
            new QueryWrapper<LeaveApplication>().eq("student_id", studentId)
        );
    }
    
    @Override
    public List<Map<String, Object>> listLeaveApplicationsForTeacher(String teacherId) {
        logger.info("获取教师相关的请假申请, 教师ID: {}", teacherId);
        // 1. 获取教师的所有课程
        QueryWrapper<Course> courseQuery = new QueryWrapper<>();
        courseQuery.eq("teacher_id", teacherId);
        List<Course> teacherCourses = courseMapper.selectList(courseQuery);
        if (teacherCourses.isEmpty()) {
            logger.info("教师没有开设课程, 教师ID: {}", teacherId);
            return new ArrayList<>();
        }
        List<String> courseIds = teacherCourses.stream()
            .map(Course::getId)
            .collect(Collectors.toList());
        logger.info("教师课程IDs: {}", courseIds);
        // 2. 查询所有请假申请（只查待审批和已批准的）
        List<LeaveApplication> allLeaves = leaveApplicationMapper.selectList(
            new QueryWrapper<LeaveApplication>().in("status", Arrays.asList("PENDING", "APPROVED"))
        );
        List<Map<String, Object>> result = new ArrayList<>();
        // 3. 筛选涉及教师课程的请假申请
        for (LeaveApplication leave : allLeaves) {
            if (leave.getAffectedCourses() != null && !leave.getAffectedCourses().isEmpty()) {
                List<String> affectedCourseIds = Arrays.asList(leave.getAffectedCourses().split(","));
                // 检查是否有交集
                boolean isRelevant = affectedCourseIds.stream()
                    .anyMatch(courseIds::contains);
                if (isRelevant) {
                    // 获取学生信息
                    User student = userMapper.selectById(leave.getStudentId());
                    if (student != null) {
                        Map<String, Object> leaveInfo = new HashMap<>();
                        leaveInfo.put("application", leave);
                        leaveInfo.put("studentName", student.getRealName());
                        leaveInfo.put("studentId", student.getUsername());
                        // 获取涉及的课程名称
                        List<String> courseNames = new ArrayList<>();
                        for (String cid : affectedCourseIds) {
                            if (courseIds.contains(cid)) {
                                Course course = courseMapper.selectById(cid);
                                if (course != null) {
                                    courseNames.add(course.getName());
                                }
                            }
                        }
                        leaveInfo.put("affectedCourseNames", String.join(", ", courseNames));
                        result.add(leaveInfo);
                    }
                }
            }
        }
        logger.info("找到与教师相关的请假申请数量: {}", result.size());
        return result;
    }
    
    @Override
    public List<Map<String, Object>> listAllLeaveApplications() {
        logger.info("获取所有请假申请");
        List<LeaveApplication> allLeaves = leaveApplicationMapper.selectList(null);
        List<Map<String, Object>> result = new ArrayList<>();
        List<Long> idList = new ArrayList<>();
        for (LeaveApplication leave : allLeaves) {
            Map<String, Object> leaveInfo = new HashMap<>();
            leaveInfo.put("application", leave);
            idList.add(leave.getId());
            
            // 获取学生信息
            User student = userMapper.selectById(leave.getStudentId());
            if (student != null) {
                leaveInfo.put("studentName", student.getRealName());
                leaveInfo.put("studentId", student.getUsername());
            } else {
                leaveInfo.put("studentName", "未知");
                leaveInfo.put("studentId", leave.getStudentId().toString());
                logger.warn("未找到学生信息，studentId: {}", leave.getStudentId());
            }
            
            // 获取涉及的课程名称
            if (leave.getAffectedCourses() != null && !leave.getAffectedCourses().isEmpty()) {
                List<String> courseNames = new ArrayList<>();
                String[] courseIds = leave.getAffectedCourses().split(",");
                for (String cid : courseIds) {
                    Course course = courseMapper.selectById(cid);
                    if (course != null) {
                        courseNames.add(course.getName());
                    }
                }
                leaveInfo.put("affectedCourseNames", String.join(", ", courseNames));
            } else {
                leaveInfo.put("affectedCourseNames", "");
            }
            
            result.add(leaveInfo);
        }
        logger.info("listAllLeaveApplications 返回的所有请假申请ID: {}", idList);
        logger.info("获取到请假申请总数: {}", result.size());
        return result;
    }
    
    @Override
    public boolean isLongTermLeave(LocalDateTime startDate, LocalDateTime endDate) {
        if (startDate == null || endDate == null) {
            return false;
        }
        
        // 计算请假天数（向上取整）
        long days = ChronoUnit.DAYS.between(startDate.toLocalDate(), endDate.toLocalDate());
        
        // 如果跨天但实际不到整天的时间，考虑具体小时
        if (days == 0 && startDate.toLocalDate().equals(endDate.toLocalDate())) {
            // 同一天内的请假，检查小时差
            long hours = ChronoUnit.HOURS.between(startDate, endDate);
            logger.info("同一天请假时长: {} 小时", hours);
            return false; // 同一天不算长期请假
        } else if (days <= 3) {
            // 如果是3天，检查具体小时是否超过3天
            if (days == 3) {
                // 计算总小时数
                long totalHours = ChronoUnit.HOURS.between(startDate, endDate);
                logger.info("3天期间请假总时长: {} 小时", totalHours);
                // 如果总小时数超过72小时（3天），则视为长期请假
                return totalHours > 72;
            }
            return false;
        }
        
        logger.info("请假时长: {} 天", days);
        return days > 3;
    }
} 